import { Types } from "uss";

type US_Result = {
  success: 1;
};

type US_Result_B = {
  success: boolean;
};

type US_xmlhttpRequest = (details: Types.Xhr.Details) => CM_Types.Xhr.Return;

type US_setValue = (key: string, value: unknown) => Promise<US_Result>;
type US_deleteValue = (key: string) => Promise<US_Result>;

type US_openInTab = (
  url: string,
  loadInBackground?: boolean,
) => Promise<browser.tabs.Tab>;
type US_closeTab = (tabId?: number) => Promise<US_Result>;

type US_getTab = () => Promise<AnyRecord>;
type US_saveTab = (tab: AnyRecord) => Promise<US_Result_B>;

type US_addStyle = (css: string) => Promise<string>;

type US_setClipboard = (data: string, type?: string) => Promise<boolean>;

interface US_ScriptInfo {
  readonly description?: string;
  readonly filename: string;
  readonly icon?: string;
  readonly "inject-into": "page" | "content" | "auto";
  readonly name: string;
  readonly namespace: string;
  readonly noframes: boolean;
  readonly resources?: string;
  readonly "run-at": `document-${"start" | "end" | "idle"}`;
  readonly version: string;
}

type US_ScriptInfoCustom = US_ScriptInfo &
  Partial<Readonly<Record<string, string[]>>>;

interface US_Info {
  readonly script: US_ScriptInfoCustom;
  readonly scriptHandler: "Userscripts";
  readonly scriptHandlerVersion: string;
  readonly scriptMetaStr: string;
}

interface US_Object {
  getValue: CM_Object["getValue"];
  setValue: US_setValue;
  listValues: CM_Object["listValues"];
  deleteValue: US_deleteValue;
  openInTab: US_openInTab;
  closeTab: US_closeTab;
  getTab: US_getTab;
  saveTab: US_saveTab;
  xmlHttpRequest: US_xmlhttpRequest;
  addStyle: US_addStyle;
  setClipboard: US_setClipboard;
  info: US_Info;
}

declare module "uss" {
  export const GM: US_Object;
  export const GM_xmlhttpRequest: US_xmlhttpRequest;
  export const GM_info: US_Info;
}
